home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / GCC / V2-4-5 / GPPLIBSR00 / cc / str < prev    next >
Text File  |  1993-12-08  |  10KB  |  580 lines

  1. /* -------------------------------------------------------------------- */
  2. /* String++ Version 2.12                                       02/16/93 */
  3. /*                                                                      */
  4. /* Enhanced string class for Turbo C++/Borland C++.                     */
  5. /* Copyright 1991-1993 by Carl W. Moreland                              */
  6. /*                                                                      */
  7. /* Str.cc                                                               */
  8. /* -------------------------------------------------------------------- */
  9.  
  10. extern "C"
  11.   {
  12.   #include <ctype.h>
  13.   #include <stdlib.h>
  14.   }
  15.  
  16.  
  17. #ifdef __GNUG__
  18. #pragma implementation "str.h"
  19. #endif
  20. #include "str.h"
  21.  
  22. /* ----- Constructors/Destructors ------------------------------------- */
  23.  
  24. string::string()
  25. {
  26.   _ptr = new char[1];            // NULL string
  27.   _ptr[0] = '\0';
  28. }
  29.  
  30. string::string(const char c, unsigned n)
  31. {
  32.   _ptr = new char[n+1];            // allocate memory for n chars
  33.  
  34.   for(int i=0; i<n; i++)
  35.     _ptr[i] = c;             // copy n chars
  36.   _ptr[i] = '\0';            // NULL terminate
  37. }
  38.  
  39. string::string(const char* s, unsigned pos, unsigned len)
  40. {
  41.   int s_len = strlen(s);
  42.  
  43.   if(pos > s_len)
  44.     pos = s_len;
  45.   if(len > s_len - pos)
  46.     len = s_len - pos;
  47.  
  48.   _ptr = new char[len+1];        // allocate new memory
  49.  
  50.   strncpy(_ptr, s+pos, len);        // copy the substring
  51.   _ptr[len] = '\0';            // need to NULL terminate
  52. }
  53.  
  54. string::string(const string& s, unsigned pos, unsigned len)
  55. {
  56.   int s_len = s.Len();
  57.  
  58.   if(pos > s_len)
  59.     pos = s_len;
  60.   if(len > s_len - pos)
  61.     len = s_len - pos;
  62.  
  63.   _ptr = new char[len+1];        // allocate new memory
  64.  
  65.   strncpy(_ptr, s(pos), len);        // copy the substring
  66.   _ptr[len] = '\0';            // need to NULL terminate
  67. }
  68.  
  69. void string::ltos(long n)
  70. {
  71.   char tmp[15];
  72. #if defined (__GNUG__)
  73.   ostrstream(tmp, 10) << n << ends;
  74. #else
  75.   ltoa(n, tmp, 10);
  76. #endif
  77.  
  78.   _ptr = new char[strlen(tmp) + 1];
  79.   strcpy(_ptr, tmp);
  80. }
  81.  
  82. string::~string(void)
  83. {
  84.   if(_ptr)
  85.     delete _ptr;
  86. }
  87.  
  88. /* -------------------------------------------------------------------- */
  89.  
  90. string& string::Right(unsigned len)
  91. {
  92.   Mid(this->Len()-len, len);
  93.   return *this;
  94. }
  95.  
  96. string& string::Left(unsigned len)
  97. {
  98.   Mid(0, len);
  99.   return *this;
  100. }
  101.  
  102. string& string::Mid(unsigned pos, unsigned len)
  103. {
  104.   int s_len = Len();
  105.  
  106.   if(pos > s_len)
  107.     pos = s_len;
  108.   if(len > s_len - pos)
  109.     len = s_len - pos;
  110.  
  111.   char *tmp = new char[len+1];        // allocate new memory
  112.  
  113.   strncpy(tmp, _ptr+pos, len);        // copy the substring
  114.   tmp[len] = '\0';            // need to NULL terminate
  115.  
  116.   delete _ptr;
  117.   _ptr = tmp;
  118.   return *this;
  119. }
  120.  
  121. string& string::Justify(int mode, unsigned len, int clip)
  122. {
  123.   Trim();                // delete outter whitespace
  124.  
  125.   int this_len = Len();
  126.  
  127.   if(this_len >= len && clip == 0)    // check for out-of-bounds
  128.     return *this;
  129.  
  130.   if(this_len > len && clip == 1)    // check for clipping
  131.   {
  132.     if(mode == LEFT)
  133.       Left(len);
  134.     else if(mode == CENTER)
  135.       Mid((this_len-len)/2, len);
  136.     else if(mode == RIGHT)
  137.       Right(len);
  138.  
  139.     return *this;            // return clipped string
  140.   }
  141.  
  142.   if(mode == LEFT)
  143.     *this = *this + string(' ', len-this_len);
  144.   else if(mode == CENTER)
  145.     *this = string(' ', (len-this_len)/2) + *this + string(' ', len - (len+this_len)/2);
  146.   else if(mode == RIGHT)
  147.     *this = string(' ', len-this_len) + *this;
  148.  
  149.   return *this;                // return normal string
  150. }
  151.  
  152. string& string::toUpper(void)
  153. {
  154.   for(int i=0; i<strlen(_ptr); i++)
  155.     _ptr[i] = ::toupper(_ptr[i]);
  156.   return *this;
  157. }
  158.  
  159. string& string::toLower(void)
  160. {
  161.   for(int i=0; i<strlen(_ptr); i++)
  162.     _ptr[i] = ::tolower(_ptr[i]);
  163.   return *this;
  164. }
  165.  
  166. int& string::Value(int& n)
  167. {
  168.   n = atoi(_ptr);
  169.   return n;
  170. }
  171.  
  172. long& string::Value(long& n)
  173. {
  174.   n = atol(_ptr);
  175.   return n;
  176. }
  177.  
  178. string& string::Insert(unsigned pos, const string& s)
  179. {
  180.   int this_len = this->Len();
  181.   int s_len = s.Len();
  182.  
  183.   if(pos > this_len)
  184.     pos = this_len;
  185.  
  186.   char *tmp = new char[this_len + s_len + 1];
  187.  
  188.   strncpy(tmp, _ptr, pos);
  189.   tmp[pos] = '\0';
  190.   strcat(tmp, s.ptr());
  191.   strcat(tmp, _ptr+pos);
  192.  
  193.   delete _ptr;
  194.   _ptr = tmp;
  195.   return *this;
  196. }
  197.  
  198. string& string::Delete(unsigned pos, unsigned len)
  199. {
  200.   int this_len = this->Len();
  201.  
  202.   if(pos >= this_len)
  203.     return *this;
  204.   if(len == 0)
  205.     return *this;
  206.   if(len > this_len - pos)
  207.     len = this_len - pos;
  208.  
  209.   char *tmp = new char[this_len-len+1];
  210.  
  211.   strncpy(tmp, _ptr, pos);
  212.   tmp[pos] = '\0';
  213.   strcat(tmp, _ptr+pos+len);
  214.  
  215.   delete _ptr;
  216.   _ptr = tmp;
  217.   return *this;
  218. }
  219.  
  220. char* string::Copy(char*& s)
  221. {
  222.   s = new char[Len() + 1];
  223.   strcpy(s, _ptr);
  224.  
  225.   return s;
  226. }
  227.  
  228. string& string::Trim(int mode, char ch)
  229. {
  230.   int begin = 0;
  231.   int end = this->Len()-1;
  232.  
  233.   if(ch == WHITESPACE)            // if we're deleting whitespaces...
  234.   {
  235.     if(mode == LEFT || mode == CENTER)    // delete leading whitespace
  236.     {
  237.       while(isspace(_ptr[begin]) && begin <= end)
  238.         begin++;
  239.     }
  240.  
  241.     if(mode == RIGHT || mode == CENTER)    // delete trailing whitespace
  242.     {
  243.       while(isspace(_ptr[end]) && end >= begin)
  244.         end--;
  245.     }
  246.   }
  247.   else                    // else a character was specified
  248.   {
  249.     if(mode == LEFT || mode == CENTER)    // delete leading characters
  250.     {
  251.       while(_ptr[begin] == ch && begin <= end)
  252.         begin++;
  253.     }
  254.  
  255.     if(mode == RIGHT || mode == CENTER)    // delete trailing characters
  256.     {
  257.       while(_ptr[end] == ch && end >= begin)
  258.         end--;
  259.     }
  260.   }
  261.  
  262.   int s_len = end-begin+1;
  263.   char *tmp = new char[s_len + 1];
  264.   strncpy(tmp, _ptr+begin, s_len);
  265.   tmp[s_len] = '\0';
  266.  
  267.   delete _ptr;
  268.   _ptr = tmp;
  269.   return *this;
  270. }
  271.  
  272. /* ----- Operators ---------------------------------------------------- */
  273.  
  274. string string::operator()(unsigned pos, unsigned len) const
  275. {
  276.   string tmp(this->_ptr, pos, len);
  277.   return tmp;
  278. }
  279.  
  280. // =
  281. string& string::operator=(const char ch)
  282. {
  283.   if(_ptr)
  284.     delete _ptr;
  285.  
  286.   _ptr = new char[2];
  287.   _ptr[0] = ch;
  288.   _ptr[1] = '\0';
  289.  
  290.   return *this;
  291. }
  292.  
  293. string& string::operator=(const char *s)
  294. {
  295.   char *tmp = _ptr;            // don't delete _ptr yet
  296.   _ptr = new char[strlen(s)+1];
  297.   strcpy(_ptr, s);
  298.  
  299.   if(tmp)
  300.     delete tmp;
  301.   return *this;
  302. }
  303.  
  304. string& string::operator=(const string& s)
  305. {
  306.   char *tmp = _ptr;            // don't delete _ptr yet
  307.   _ptr = new char[s.Len()+1];
  308.   strcpy(_ptr, s.ptr());
  309.  
  310.   if(tmp)
  311.     delete tmp;
  312.   return *this;
  313. }
  314.  
  315. string& string::operator=(const int n)
  316. {
  317.   if(_ptr)
  318.     delete _ptr;
  319.  
  320.   char tmp[15];
  321. #if defined (__GNUG__)
  322.   ostrstream(tmp, 10) << n << ends;
  323. #else
  324.   itoa(n, tmp, 10);
  325. #endif
  326.  
  327.   _ptr = new char[strlen(tmp) + 1];
  328.   strcpy(_ptr, tmp);
  329.  
  330.   return *this;
  331. }
  332.  
  333. // +
  334. string operator+(const string& s1, const char *s2)
  335. {
  336.   string tmp(s1);
  337.   tmp += s2;
  338.   return tmp;
  339. }
  340.  
  341. string operator+(const char *s1, const string& s2)
  342. {
  343.   string tmp(s1);
  344.   tmp += s2;
  345.   return tmp;
  346. }
  347.  
  348. string operator+(const string& s1, const string& s2)
  349. {
  350.   string tmp(s1);
  351.   tmp += s2;
  352.   return tmp;
  353. }
  354.  
  355. // +=
  356. string& string::operator+=(const char ch)
  357. {
  358.   char *tmp = _ptr;
  359.   int this_len = this->Len();
  360.  
  361.   _ptr = new char[this_len + 2];
  362.  
  363.   strcpy(_ptr, tmp);
  364.   _ptr[this_len]   = ch;
  365.   _ptr[this_len+1] = '\0';
  366.  
  367.   if(tmp)
  368.     delete tmp;
  369.   return *this;
  370. }
  371.  
  372. string& string::operator+=(const char *s)
  373. {
  374.   char *tmp = _ptr;
  375.  
  376.   _ptr = new char[strlen(tmp) + strlen(s) + 1];
  377.  
  378.   strcpy(_ptr, tmp);
  379.   strcat(_ptr, s);
  380.  
  381.   if(tmp)
  382.     delete tmp;
  383.   return *this;
  384. }
  385.  
  386. string& string::operator+=(const string& s)
  387. {
  388.   char *tmp = _ptr;
  389.   _ptr = new char[strlen(tmp) + s.Len() + 1];
  390.  
  391.   strcpy(_ptr, tmp);
  392.   strcat(_ptr, s.ptr());
  393.  
  394.   if(tmp)
  395.     delete tmp;
  396.   return *this;
  397. }
  398.  
  399. // *
  400. string operator*(const string& s1, int n)
  401. {
  402.   string tmp(s1);
  403.  
  404.   for(int i=1; i<n; i++)
  405.     tmp += s1;
  406.   return tmp;
  407. }
  408.  
  409. // *=
  410. string& string::operator*=(unsigned n)
  411. {
  412.   char *tmp = _ptr;
  413.  
  414.   _ptr = new char[n*strlen(tmp) + 1];
  415.  
  416.   strcpy(_ptr, tmp);
  417.   for(int i=1; i<n; i++)
  418.     strcat(_ptr, tmp);
  419.  
  420.   if(tmp)
  421.     delete tmp;
  422.   return *this;
  423. }
  424.  
  425. // []
  426. char& string::operator[](unsigned n) const
  427. {
  428.   if(n >= Len())
  429.     n = Len()-1;
  430.   return *(_ptr + n);
  431. }
  432.  
  433. /* -------------------------------------------------------------------- */
  434. /* AWK-style functions                                                  */
  435. /* -------------------------------------------------------------------- */
  436.  
  437. int index(const string& s, const string& t)
  438. {
  439.   int pos;
  440.   char *tmp;
  441.  
  442.   if((tmp = strstr(s.ptr(), t.ptr())) != NULL)
  443.     pos = (int)(tmp-(const)s.ptr());
  444.   else
  445.     pos = -1;
  446.  
  447.   return pos;
  448. }
  449.  
  450. string substr(const string& s, unsigned p, unsigned n)
  451. {
  452.   string tmp = mid(s, p, n);
  453.   return tmp;
  454. }
  455.  
  456. int split(const string& s, string*& array, const string& fs)
  457. {
  458.   int i=0, j=1, start=0;
  459.   int fs_len = fs.Len();
  460.   int s_len = s.Len();
  461.   string *tmp;
  462.  
  463.   while(i < s_len)
  464.   {
  465.     if(strncmp(s(i), fs(), fs_len) == 0)
  466.       j++;
  467.     i++;
  468.   }
  469.   tmp = new string[j];
  470.   i = 0;
  471.   j = 0;
  472.  
  473.   while(i < s_len)
  474.   {
  475.     if(strncmp(s(i), fs(), fs_len) == 0)
  476.     {
  477.       tmp[j++] = string(mid(s, start, i-start));
  478.       i += fs_len;
  479.       start = i;
  480.     }
  481.     else
  482.       i++;
  483.   }
  484.   tmp[j++] = mid(s, start, i-start);
  485.  
  486.   array = tmp;
  487.   return j;
  488. }
  489.  
  490. int gsub(const string& from, const string& to, string& str, unsigned count)
  491. {
  492.   int i=0, j=0;
  493.   int from_len, to_len;
  494.  
  495.   from_len = from.Len();
  496.   to_len = to.Len();
  497.  
  498.   while(i <= str.Len()-from_len)
  499.   {
  500.     if(strncmp(str(i), from(), from_len) == 0)
  501.     {
  502.       str = left(str, i) + to + right(str, str.Len()-i-from_len);
  503.       i += to_len;
  504.       if(++j == count)
  505.         break;
  506.     }
  507.     else
  508.       i++;
  509.   }
  510.   return j;
  511. }
  512.  
  513. /* -------------------------------------------------------------------- */
  514. /* C-style functions                            */
  515. /* -------------------------------------------------------------------- */
  516.  
  517. string toupper(const string& s)
  518. {
  519.   string tmp(s);
  520.   tmp.toupper();
  521.   return tmp;
  522. }
  523.  
  524. string tolower(const string& s)
  525. {
  526.   string tmp(s);
  527.   tmp.tolower();
  528.   return tmp;
  529. }
  530.  
  531. string left(const string& s, unsigned len)
  532. {
  533.   string tmp(s, 0, len);
  534.   return tmp;
  535. }
  536.  
  537. string right(const string& s, unsigned len)
  538. {
  539.   string tmp(s, s.Len()-len, len);
  540.   return tmp;
  541. }
  542.  
  543. string mid(const string& s, unsigned pos, unsigned len)
  544. {
  545.   string tmp(s, pos, len);
  546.   return tmp;
  547. }
  548.  
  549. string justify(const string& s, int mode, unsigned len, int clip)
  550. {
  551.   string tmp(s);
  552.   tmp.Justify(mode, len, clip);
  553.   return tmp;
  554. }
  555.  
  556. string trim(const string& s, int mode)
  557. {
  558.   string tmp(s);
  559.   tmp.Trim(mode);
  560.   return tmp;
  561. }
  562.  
  563. /* ----- Stream I/O --------------------------------------------------- */
  564.  
  565. ostream& operator<<(ostream& s, const string& str)
  566. {
  567.   return s << str();
  568. }
  569.  
  570. istream& operator>>(istream& s, string& str)
  571. {
  572.   char p[256];
  573.  
  574.   s >> p;
  575.   str = p;
  576.  
  577.   return s;
  578. }
  579.  
  580.